home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1996 February / macformat-034.iso / mac / Shareware City / Developers / appe Windows 2.03 / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-28  |  8.0 KB  |  292 lines  |  [TEXT/CWIE]

  1. // File "main.c" - 
  2.  
  3. #include <GestaltEqu.h>
  4. #include <TextServices.h>
  5. #include <Traps.h>
  6.  
  7. #include "main.h"
  8. #include "aevents.h"
  9. #include "filter.h"
  10. #include "floaters.h"
  11. #include "notify.h"
  12. #include "patches.h"
  13. #include "sample win.h"
  14.  
  15. // * ****************************************************************************** *
  16. // Global Declarations
  17.  
  18. GlobalsRec glob;
  19.  
  20. // * ****************************************************************************** *
  21. // * ****************************************************************************** *
  22.  
  23. void DoTest() {
  24.     short i;
  25.     long response;
  26.     
  27.     for(i=0; i<sizeof(glob); ((char *) &glob)[i++] = 0);
  28.     
  29.     // Simple Tests for compatibility
  30.     if (Gestalt(gestaltSystemVersion, &response) || (response < 0x0604) ||
  31.             Gestalt(gestaltTSMgrVersion, &response))
  32.         UserNotify(kNotifyStringList, kSys71NotifyString, TRUE);
  33.         
  34.     // I could look at my ProcessInfoRec, but this is a single line solution
  35.     glob.bkgdOnly = ((** (short **) GetResource('SIZE', -1)) & 0x0400) ? TRUE : FALSE;
  36.     glob.hasColorQD = (! Gestalt(gestaltQuickdrawFeatures, &response) &&
  37.             (response & (1 << gestaltHasColor))) ? TRUE : FALSE;
  38.     glob.hasGDevices = (NGetTrapAddress(_GetDeviceList, ToolTrap) !=
  39.             NGetTrapAddress(_Unimplemented, ToolTrap)) ? TRUE : FALSE;
  40.     glob.hasDragMgr = (! Gestalt(gestaltDragMgrAttr, &response) &&
  41.             (response & (1 << gestaltDragMgrPresent))) ? TRUE : FALSE;
  42.  
  43.     // Inform the user how to find the "TSM Fix" if it isn't installed
  44.     if (Gestalt('TSM+', &response))
  45.         UserNotify(kNotifyStringList, kTSMFixNotifyString, FALSE);
  46.     }
  47.  
  48. // * ****************************************************************************** *
  49. // * ****************************************************************************** *
  50.  
  51. void DoInit() {
  52.     long saveA5;
  53.     
  54.     // 'appe' programs get 8k of Stack Space by default -- we need MORE! 
  55.     if (glob.bkgdOnly) SetApplLimit(GetApplLimit() - 16384);
  56.     MaxApplZone();
  57.     MoreMasters();
  58.  
  59.     // Basic Initialization 
  60.     InitGraf(&qd.thePort);
  61.     
  62.     // Finish our Initialization - but only if we are a foreground app. Apple
  63.     //   warns loudly that bkgd-only apps should not call InitWindows(), etc.
  64.     if (! glob.bkgdOnly) {
  65.         InitFonts();
  66.         InitWindows();
  67.         InitMenus();
  68.         TEInit();
  69.         InitDialogs(0);
  70.         InitCursor();
  71.         
  72.         InsertMenu(GetMenu(kAppleMenuID), 0);
  73.         AddResMenu(GetMHandle(kAppleMenuID), 'DRVR');
  74.         InsertMenu(GetMenu(kFileMenuID), 0);
  75.         InsertMenu(GetMenu(kEditMenuID), 0);
  76.         DisableItem(GetMHandle(kEditMenuID), 0);
  77.         
  78.         DrawMenuBar();
  79.         }
  80.       else {
  81.         // After reading the above, you know that you can't call any other toolbox
  82.         //   init stuff. However, FindServiceWindow() fails if the MenuList lomem 
  83.         //   global is NIL! This is a moderate (but not recommended) workaround.
  84.         InitFonts();
  85.         InitMenus();
  86.         }
  87.     
  88.     PatchNewWindow();
  89.     PatchExitToShell();
  90.  
  91.     // Save this information for later
  92.     GetCurrentProcess(&glob.myPSN);    
  93.         
  94.     // Install an event filter or die
  95.     SetA5(saveA5 = SetA5(0));
  96.     glob.filterProc =
  97.             (Ptr) InstallEventFilter((FilterHelperUPP) EventFilterHelper, (Ptr) saveA5);
  98.     if (! glob.filterProc)
  99.         UserNotify(kNotifyStringList, kJGNENotifyString, TRUE);
  100.     
  101.     InitHLEvents();
  102.     NewSampleWindow();
  103.     }
  104.  
  105. // * ****************************************************************************** *
  106. // * ****************************************************************************** *
  107.  
  108. void DoLoop() {
  109.     Boolean floaterEvent;
  110.     
  111.     while(! glob.quitting) {
  112.         // If there are no internal events pending, then we call WNE() with a
  113.         //   moderate delay. Otherwise, we want to make a fast response to any 
  114.         //   floater events, so we make sure the event filter will wake us up quickly.
  115.         if (! glob.forwardedEvents.qHead) 
  116.             WaitNextEvent(everyEvent, &glob.theEvent, 150, 0);    // Sleep for 2.5 secs
  117.         
  118.         // If nothing to do, then check our private event queue to see if any
  119.         //   clicks or keydowns are pending for our floater windows.
  120.         floaterEvent = (glob.theEvent.what != nullEvent) ? FALSE : 
  121.                 GetFloaterEvent(&glob.theEvent);
  122.         
  123.         // Check the states of our floaters, then generate and handle any 
  124.         //   pending Update Events for floaters because the Event Mgr will
  125.         //   not generate them for us.
  126.         ShowHideFloater(0);
  127.         UpdateFloater(0);
  128.  
  129.         switch(glob.theEvent.what) {
  130.             case nullEvent:
  131.                 break;
  132.             case mouseDown: {
  133.                 short thePart;
  134.                 Rect bounds;
  135.                 WindowPtr whichWin, frontWin;
  136.                 
  137.                 if (floaterEvent) {
  138.                     thePart = FindServiceWindow(glob.theEvent.where, &whichWin);
  139.                     if (GetFrontServiceWindow(&frontWin)) frontWin = 0;
  140.                     }
  141.                   else {
  142.                     thePart = FindWindow(glob.theEvent.where, &whichWin);
  143.                     frontWin = FrontWindow();
  144.                     }
  145.  
  146.                 glob.theEvent.message = thePart;        
  147.                 switch(thePart) {
  148.                     case inMenuBar:
  149.                         DoMenuItem(MenuSelect(glob.theEvent.where));
  150.                         break;
  151.                         
  152.                     case inSysWindow:
  153.                         SystemClick(&glob.theEvent, whichWin);
  154.                         break;
  155.                         
  156.                     case inDrag:
  157.                         if (whichWin != frontWin) {
  158.                             SelectWindow(whichWin);
  159.                             UpdateFloater(whichWin);
  160.                             }
  161.                         bounds = (*GetGrayRgn())->rgnBBox;
  162.                         DragWindow(whichWin, glob.theEvent.where, &bounds);
  163.                         UpdateFloater(whichWin);
  164.                         break;
  165.                         
  166.                     case inContent:
  167.                     case inGrow:
  168.                     case inGoAway:
  169.                     case inZoomIn:
  170.                     case inZoomOut:
  171.                         if (whichWin != frontWin) {
  172.                             SelectWindow(whichWin);
  173.                             UpdateFloater(whichWin);
  174.                             }
  175.                         EventDispatchFloaters(&glob.theEvent, whichWin);
  176.                         break;
  177.                     }
  178.                 break;
  179.                 }
  180.             case keyDown:
  181.             case autoKey: {
  182.                 char theKey, theChar;
  183.                 
  184.                 theChar = glob.theEvent.message & charCodeMask;
  185.                 theKey = (glob.theEvent.message & keyCodeMask) >> 8;
  186.                 
  187.                 if (glob.theEvent.modifiers & cmdKey)
  188.                     DoMenuItem(MenuKey(glob.theEvent.message & charCodeMask));
  189.                   else EventDispatchFloaters(&glob.theEvent, 0);
  190.                 }
  191.                 break;
  192.                     
  193.             case updateEvt:
  194.                 if (GetOneFloater((WindowPtr) glob.theEvent.message, FALSE))
  195.                     EventDispatchFloaters(&glob.theEvent, (WindowPtr) glob.theEvent.message);
  196.                 break;
  197.             case activateEvt:
  198.                 break;
  199.             case kHighLevelEvent:
  200.                 AEProcessAppleEvent(&glob.theEvent);
  201.                 break;
  202.             }
  203.         
  204.         // WARNING: Dont set the cursor to arrow just because it is over a floater
  205.         //   window -- most foreground apps are not smart enough to recognize a
  206.         //   the TSM floaters, and the cursor may start to flicker.
  207.         if (! glob.bkgdOnly) SetCursor(&qd.arrow);
  208.         }
  209.     }
  210.  
  211. // * ****************************************************************************** *
  212. // * ****************************************************************************** *
  213.  
  214. void DoMenuItem(long theMenuAndItem) {
  215.     short theMenu, theItem;
  216.     Str63 theString;
  217.     
  218.     if (! theMenuAndItem) return;
  219.     
  220.     theMenu = (theMenuAndItem & 0xFFFF0000) >> 16;
  221.     theItem = theMenuAndItem & 0x0000FFFF;
  222.     
  223.     switch(theMenu) {
  224.         case kAppleMenuID:
  225.             if (theItem == kAppleMenuAboutItem) {
  226.                 // Block out the floaters while we display our about box... 
  227.                 //   then enable and update them after we have finished.
  228.                 glob.modalFloats = TRUE;
  229.                 ShowHideFloater(0);
  230.                 
  231.                 Alert(128, 0);
  232.                 
  233.                 glob.modalFloats = FALSE;
  234.                 ShowHideFloater(0);
  235.                 UpdateFloater(0);
  236.                 }
  237.               else {
  238.                 GetItem(GetMHandle(theMenu), theItem, theString);
  239.                 OpenDeskAcc(theString);
  240.                 }
  241.             break;
  242.             
  243.         case kFileMenuID:
  244.             switch(theItem) {
  245.                 case kFileMenuNewItem:
  246.                     NewSampleWindow();
  247.                     break;
  248.                 case kFileMenuQuitItem:
  249.                     glob.quitting = TRUE;
  250.                     break;
  251.                 }
  252.             break;
  253.             
  254.         case kEditMenuID:
  255.             break;
  256.  
  257.         default:
  258.             break;
  259.         }
  260.     HiliteMenu(0);
  261.     DrawMenuBar();
  262.     }
  263.  
  264. // * ****************************************************************************** *
  265. // * ****************************************************************************** *
  266.  
  267. void DoDispose() {
  268.     static Boolean done = FALSE;
  269.     
  270.     // Our ExitToShell() patch may cause re-entrancy problems... so we bracket
  271.     //   the functional calls by checking and setting a one-time flag.
  272.     if (! done) {
  273.         done = TRUE;
  274.         
  275.         CloseRemainingFloaters();
  276.         
  277.         ReleaseEventFilter(glob.filterProc);
  278.         glob.filterProc = 0;
  279.         }
  280.     }
  281.         
  282. // * ****************************************************************************** *
  283. // * ****************************************************************************** *
  284.  
  285. void main() {
  286.     DoTest();
  287.     DoInit();
  288.     DoLoop();
  289.     DoDispose();
  290.     }
  291.     
  292.